package cn.edu.seig.vibemusic.service.impl;

import cn.edu.seig.vibemusic.constant.MessageConstant;
import cn.edu.seig.vibemusic.service.MinioService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.ListObjectsArgs;
import io.minio.Result;
import io.minio.messages.Item;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class MinioServiceImpl implements MinioService {

    private final MinioClient minioClient;

    @Value("${minio.bucket}")
    public String bucketName;

    @Value("${minio.endpoint}")
    public String endpoint;

    // 新增公共的 setter 方法
    public void setBucketName(String bucketName) {
        this.bucketName = bucketName;
    }

    public void setEndpoint(String endpoint) {
        this.endpoint = endpoint;
    }

    public MinioServiceImpl(MinioClient minioClient) {
        this.minioClient = minioClient;
    }

    /**
     * 上传文件到 Minio
     *
     * @param file   文件
     * @param folder 文件夹
     * @return 可访问的 URL
     */
    @Override
    public String uploadFile(MultipartFile file, String folder) {
        try {
            // 生成唯一文件名
            String fileName = folder + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();

            // 获取文件流
            InputStream inputStream = file.getInputStream();

            // 上传文件
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(fileName)
                            .stream(inputStream, file.getSize(), -1)
                            .contentType(file.getContentType())
                            .build()
            );

            // 返回可访问的 URL
            return endpoint + "/" + bucketName + "/" + fileName;

        } catch (Exception e) {
            throw new RuntimeException(MessageConstant.FILE_UPLOAD + MessageConstant.FAILED + "：" + e.getMessage());
        }
    }

    /**
     * 删除文件
     *
     * @param fileUrl 文件 URL
     */
    @Override
    public void deleteFile(String fileUrl) {
        try {
            // 解析 URL，获取文件路径
            String filePath = fileUrl.replace(endpoint + "/" + bucketName + "/", "");

            // 删除文件
            minioClient.removeObject(
                    RemoveObjectArgs.builder()
                            .bucket(bucketName)
                            .object(filePath)
                            .build()
            );

        } catch (Exception e) {
            throw new RuntimeException("文件删除失败: " + e.getMessage());
        }
    }

    /**
     * 获取指定文件夹下的所有图片URL
     *
     * @param folder 文件夹名称
     * @return 图片URL列表
     */
    @Override
    public List<String> listImages(String folder) {
        List<String> imageUrls = new ArrayList<>();
        try {
            // 构建查询参数
            ListObjectsArgs listArgs = ListObjectsArgs.builder()
                    .bucket(bucketName)
                    .prefix(folder + "/")
                    .recursive(true)
                    .build();

            // 获取所有对象
            Iterable<Result<Item>> results = minioClient.listObjects(listArgs);

            // 遍历结果并过滤图片文件
            for (Result<Item> result : results) {
                Item item = result.get();
                String objectName = item.objectName();
                
                // 检查文件扩展名是否为图片格式
                if (isImageFile(objectName)) {
                    String imageUrl = endpoint + "/" + bucketName + "/" + objectName;
                    imageUrls.add(imageUrl);
                }
            }

            return imageUrls;
        } catch (Exception e) {
            throw new RuntimeException("获取图片列表失败: " + e.getMessage());
        }
    }

    /**
     * 检查文件是否为图片
     *
     * @param fileName 文件名
     * @return 是否为图片
     */
    private boolean isImageFile(String fileName) {
        String[] imageExtensions = {".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"};
        String lowerFileName = fileName.toLowerCase();
        for (String extension : imageExtensions) {
            if (lowerFileName.endsWith(extension)) {
                return true;
            }
        }
        return false;
    }
}
